package ru.niir.goodfil.ui.utils;

import org.apache.log4j.Logger;
import ru.niir.goodfil.db.Client;
import ru.niir.goodfil.db.GoodfilFactory;
import ru.niir.goodfil.db.Order;
import ru.niir.goodfil.db.User;
import ru.niir.goodfil.db.handlers.Goodfil;
import ru.niir.goodfil.ui.RestsExportBean;
import ru.niir.goodfil.ui.Utils;

import javax.activation.DataHandler;
import javax.activation.DataSource;
import javax.activation.FileDataSource;
import javax.faces.model.SelectItem;
import javax.mail.*;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeBodyPart;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMultipart;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.util.*;

public class RestsExportManager {
    private static final Logger logger = Logger.getLogger(RestsExportManager.class);

    private static Map<String, String> config = initConfig();

    public static synchronized void sendSafe(Goodfil g,long clientI) throws IOException, MessagingException {
        send(g,clientI);
    }

    public static void send(Goodfil gf, long clientId)
            throws IOException, MessagingException {
        if (gf == null) {
            gf = GoodfilFactory.getInstance();
        }

        logger.debug("Sending rests for client: " + clientId);
        Client client = gf.getClientById(clientId);
        if (client == null) {
            logger.error("Cannot send rests for client: " + clientId + ", client is missing");
            return;
        }

        logger.debug("Defining constants");

        gf.createIfNotExists(".temp", "C:\\Temp", "Каталог для временных файлов");
        String tempCatalog = gf.get(".temp");

        gf.createIfNotExists(".rests.export.template", "C:\\template.xls", "Путь к шаблону Excel для выгрузки остатков");
//        String templatePath = "/home/sazonov/templates/rests_template3.xls";
        String templatePath = gf.get(".rests.export.template");

        String uid = UUID.randomUUID().toString();
        String tempFile = tempCatalog + File.separator + uid + ".xls";

        logger.debug("Generating report");
        RestsExportBean.generateReport(gf, clientId, templatePath, tempFile);

        logger.debug("Sending report");
        gf.createIfNotExists(".smtp.host", "192.168.0.2", "Адрес почтового сервера в сети");
        gf.createIfNotExists(".smtp.port", "587", "Порт для доступа к почтовому серверу");
        gf.createIfNotExists(".smtp.username", "zakaz", "Имя пользователя для доступа к почтовому серверу");
        gf.createIfNotExists(".smtp.password", "50065", "Пароль для доступа к почтовому серверу");

        String host = gf.get(".smtp.host");
        String port = gf.get(".smtp.port");
        String username = gf.get(".smtp.username");
        String password = gf.get(".smtp.password");

        String caption = "Остатки GoodWill на " + Utils.getTodayDateAsString() + "г.";

        URL url = new URL("http://catalog-new.goodfil.com/Zip1001/Unsubscribe.jsf?userid=" + client.getId());

        String body = "Уважаемые партнеры!<br />Настоящим письмом Вам высылаются сведения о текущих остатках продукции GoodWill на " + Utils.getTodayDateAsString() + "г.<br />" + "Это письмо было сгенерировано автоматически, отвечать на него не надо. " +
                "Если Вы считаете, что данное письмо отправлено без Вашей санкции, пожалуйста, сообщите нам по адресу info@goodfil.com.\n" +
                "Вы также можете "+ "<a href="+url+">изменить условия рассылки или отказаться</a>. <br />" + "С Уважением,<br />администрация Goodwill.";

        logger.warn("@@@ client: " + client.getId() + " " + client.getCompanyName());
        sendEmailWithAttachment(host, port, username, password, client.getContactEmail(), caption, body, tempFile, "Ostatki.xls");
    }

    /**
     * Метод выполняет отправку уведомления о заказе, с вложением в виде excel-файла с информацией о заказе
     * @param gf
     * @param clientId
     * @param orderId
     * @throws IOException
     * @throws MessagingException
     */
    public synchronized void sendCalculation(Goodfil gf, long userId, long orderId)
            throws IOException, MessagingException {
        if (gf == null) {
            gf = GoodfilFactory.getInstance();
        }

        User user = gf.getUserById(userId);
        if(user == null){
            logger.error("Не установлен менеджер");
        }
        logger.debug("Defining constants");
        String fileName = orderId + ".xls";
        String tempFile = "C:\\is\\temp\\заказ № " + orderId + ".xls";

        logger.debug("Sending report");
        gf.createIfNotExists(".smtp.host", "192.168.0.2", "Адрес почтового сервера в сети");
        gf.createIfNotExists(".smtp.port", "587", "Порт для доступа к почтовому серверу");
        gf.createIfNotExists(".smtp.username", "zakaz", "Имя пользователя для доступа к почтовому серверу");
        gf.createIfNotExists(".smtp.password", "50065", "Пароль для доступа к почтовому серверу");

        String host = gf.get(".smtp.host");
        String port = gf.get(".smtp.port");
        String username = gf.get(".smtp.username");
        String password = gf.get(".smtp.password");

        String caption = "Счет на заказ " + orderId;

        String body = "Уважаемые партнеры!<br />Настоящим письмом Вам высылается сборочная накладная на заказ " + orderId + ". Это письмо было сгенерировано автоматически, отвечать на него не надо. <br /> Если Вы считаете, что данное письмо отправлено без Вашей санкции, пожалуйста, сообщите нам по адресу info@goodfil.com. <br />" + "С Уважением,<br />администрация Goodwill.";

        sendEmailWithAttachment(host, port, username, password, user.getEmail(), caption, body, tempFile, fileName);
    }

    public static void sendEmailWithAttachment(String smtpHost, String port, String username, String password, String email, String caption, String body, String attachmentFile, String fileName) throws MessagingException {
        Properties props = new Properties();
        props.put("mail.smtp.host", smtpHost);
        props.put("mail.smtp.port", port);
        //props.put("mail.smtp.auth", "true");
        //props.put("mail.smtp.starttls.enable", "true");
        //props.put("mail.debug", "true");

        Session session = Session.getInstance(props, new SMTPAuthenticator(username, password));
        String[] emails = email.split(";");
        for (String em : emails) {
            em = em.trim();
            if (em.equals("")) {
                continue;
            }

            MimeMessage message = new MimeMessage(session);
            message.setFrom(new InternetAddress(username));
            message.setSubject(caption, "UTF-8");

            Multipart multipart = new MimeMultipart();

            MimeBodyPart messageBodyPart = new MimeBodyPart();
            messageBodyPart.setText(body, "UTF-8", "html");
            multipart.addBodyPart(messageBodyPart);

            messageBodyPart = new MimeBodyPart();

            DataSource source = new FileDataSource(attachmentFile);
            messageBodyPart.setDataHandler(new DataHandler(source));
            messageBodyPart.setFileName(fileName);
            multipart.addBodyPart(messageBodyPart);
            message.setContent(multipart);
            message.addRecipient(Message.RecipientType.TO, new InternetAddress(em));

            Transport.send(message);
        }
    }

    public static synchronized void sendOrderRemoveMessageForStoreKeeper(Goodfil gf, long orderId)
            throws IOException, MessagingException {
        if (gf == null) {
            gf = GoodfilFactory.getInstance();
        }

        User user = gf.getUserById(126);
        Order order = gf.getOrderById(orderId);
        order.setClient(gf.getClientById(order.getClientId()));
        if(user == null){
            logger.error("Не установлен менеджер");
        }
        logger.debug("Defining constants");

        logger.debug("Sending report");
        gf.createIfNotExists(".smtp.host", "192.168.0.2", "Адрес почтового сервера в сети");
        gf.createIfNotExists(".smtp.port", "587", "Порт для доступа к почтовому серверу");
        gf.createIfNotExists(".smtp.username", "zakaz", "Имя пользователя для доступа к почтовому серверу");
        gf.createIfNotExists(".smtp.password", "50065", "Пароль для доступа к почтовому серверу");

        String host = gf.get(".smtp.host");
        String port = gf.get(".smtp.port");
        String username = gf.get(".smtp.username");
        String password = gf.get(".smtp.password");

        String caption = "Уведомление об удалении заказа " + orderId;

        String body = "Уважаемые партнеры!<br /> Сообщаем Вам, что заказ № " + orderId + " клиента " + order.getClient().getCompanyName() + " , дата отгрузки: " + order.getDeliveryDateAsString() +
                "был удален. Это письмо было сгенерировано автоматически, отвечать на него не надо." + "<br />С Уважением,<br />администрация Goodwill.";

        sendEmail(host, port, username, password, user.getEmail(), caption, body);
    }

    public static synchronized void sendOrderChangeMessageForStoreKeeper(Goodfil gf, long orderId)
            throws IOException, MessagingException {
        if (gf == null) {
            gf = GoodfilFactory.getInstance();
        }

        User user = gf.getUserById(126);
        Order order = gf.getOrderById(orderId);
        order.setClient(gf.getClientById(order.getClientId()));
        if(user == null){
            logger.error("Не установлен менеджер");
        }
        logger.debug("Defining constants");

        logger.debug("Sending report");
        gf.createIfNotExists(".smtp.host", "192.168.0.2", "Адрес почтового сервера в сети");
        gf.createIfNotExists(".smtp.port", "587", "Порт для доступа к почтовому серверу");
        gf.createIfNotExists(".smtp.username", "zakaz", "Имя пользователя для доступа к почтовому серверу");
        gf.createIfNotExists(".smtp.password", "50065", "Пароль для доступа к почтовому серверу");

        String host = gf.get(".smtp.host");
        String port = gf.get(".smtp.port");
        String username = gf.get(".smtp.username");
        String password = gf.get(".smtp.password");

        String caption = "Уведомление об изменении заказа " + orderId;

        String body = "Уважаемые партнеры!<br /> Сообщаем Вам, что в заказе № " + orderId + " клиента " + order.getClient().getCompanyName() + " была изменена дата отгрузки, новая дата: " + order.getDeliveryDateAsString() +
                ". Данный заказ добавлен в лист развоза на соответствующую дату. Это письмо было сгенерировано автоматически, отвечать на него не надо.<br />" + "С Уважением,<br />администрация Goodwill.";

        sendEmail(host, port, username, password, user.getEmail(), caption, body);
    }

    public static synchronized void sendStorageDeliveryChangeMessageForStoreKeeper(Goodfil gf, long orderId)
            throws IOException, MessagingException {
        if (gf == null) {
            gf = GoodfilFactory.getInstance();
        }

        User user = gf.getUserById(126);
        Order order = gf.getOrderById(orderId);
        order.setClient(gf.getClientById(order.getClientId()));
        if(user == null){
            logger.error("Не установлен менеджер");
        }
        logger.debug("Defining constants");

        logger.debug("Sending report");
        gf.createIfNotExists(".smtp.host", "192.168.0.2", "Адрес почтового сервера в сети");
        gf.createIfNotExists(".smtp.port", "587", "Порт для доступа к почтовому серверу");
        gf.createIfNotExists(".smtp.username", "zakaz", "Имя пользователя для доступа к почтовому серверу");
        gf.createIfNotExists(".smtp.password", "50065", "Пароль для доступа к почтовому серверу");

        String host = gf.get(".smtp.host");
        String port = gf.get(".smtp.port");
        String username = gf.get(".smtp.username");
        String password = gf.get(".smtp.password");

        String caption = "Уведомление об удалении заказа из листа развоза " + orderId;

        String body = "Уважаемые партнеры!<br /> Сообщаем Вам, что заказ № " + orderId + " клиента " + order.getClient().getCompanyName() + " , дата отгрузки: " + order.getDeliveryDateAsString() +
                "был удален из листа развоза. Это письмо было сгенерировано автоматически, отвечать на него не надо.<br />" + "С Уважением,<br />администрация Goodwill.";

        sendEmail(host, port, username, password, user.getEmail(), caption, body);
    }


    public static void sendEmail(String smtpHost, String port, String username, String password, String email, String caption, String body) throws MessagingException {
        Properties props = new Properties();
        props.put("mail.smtp.host", smtpHost);
        props.put("mail.smtp.port", port);
      //  props.put("mail.smtp.auth", "true");
      //  props.put("mail.debug", "true");
        Session session = Session.getInstance(props, new SMTPAuthenticator(username, password));

        String[] emails = email.split(";");
        for (String em : emails) {
            em = em.trim();
            if (em.equals("")) {
                continue;
            }

            MimeMessage message = new MimeMessage(session);
            message.setFrom(new InternetAddress(username));
            message.setSubject(caption, "UTF-8");

            Multipart multipart = new MimeMultipart();

            MimeBodyPart messageBodyPart = new MimeBodyPart();
            messageBodyPart.setText(body, "UTF-8", "html");
            multipart.addBodyPart(messageBodyPart);

            message.setContent(multipart);
            message.addRecipient(Message.RecipientType.TO, new InternetAddress(em));

            Transport.send(message);
        }
    }


    private static Map<String, String> initConfig() {
        Map<String, String> config = new HashMap<String, String>();
        config.put("0 9 * * *", "1 раз в день(в 09:00)");
        config.put("0 9,15 * * *", "2 раза в день(в 09:00 и в 15:00)");
        config.put("0 9,19 * * *", "2 раза в день(в 09:00 и в 19:00)");
        config.put("0 9,13,16 * * *", "3 раза в день(в 09:00, в 13:00 и в 16:00)");
        config.put("0 9 * * 1,5","2 раза в неделю(Пн. и пт. в 09:00)");
        config.put("0 9 * * 2,4","2 раза в неделю(Вт. и чт. в 09:00)");
        config.put("0 9 * * 1,3,5","3 раза в неделю(Пн., ср. и пт. в 09:00)");
        config.put("0 9 * * 1", "1 раз в неделю(Пн. в 09:00)");
        config.put("0 9 1 * *", "1 раз в месяц(1 числа в 09:00)");
        return config;
    }

    public static List<SelectItem> selects() {
        List<SelectItem> result = new ArrayList<SelectItem>();

        for (String key : config.keySet()) {
            String value = config.get(key);
            result.add(new SelectItem(key, value));
        }

        return result;
    }

    public static String getValueByKey(String key) {
        return config.get(key);
    }

    public static String getFirst() {
        return "0 9 * * Mon";
    }
}